{
  "openapi": "3.1.0",
  "info": {
    "title": "API Tài nguyên chung",
    "description": "API quản lý tài nguyên chung cho proxy, nhóm và thẻ. Các tài nguyên này được sử dụng bởi cả Hồ sơ trình duyệt và Điện thoại đám mây. URL cơ sở: `http://127.0.0.1:40000`",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxies",
      "description": "Các API liên quan đến Proxies."
    },
    {
      "name": "Groups",
      "description": "Các API liên quan đến Groups."
    },
    {
      "name": "Tags",
      "description": "Các API liên quan đến Tags."
    },
    {
      "name": "Webhooks",
      "description": "API cho cấu hình webhook của nhóm."
    }
  ],
  "paths": {
    "/api/proxyInfo/page": {
      "post": {
        "summary": "Lấy danh sách máy chủ proxy",
        "deprecated": false,
        "description": "Liệt kê theo trang các cấu hình proxy của nhóm.\n- **Tác động**: không có. Chỉ đọc. An toàn khi thử lại với thời gian chờ tăng dần có giới hạn.\n- **Lưu ý**: mật khẩu không được trả về cho thành viên thường, cũng như với proxy cloud và proxy động. Proxy động xuất hiện ở đây nhưng được quản lý ở nơi khác và không thể sửa qua các endpoint proxy.",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "ID proxy tùy chọn để khớp chính xác. Gửi ID 64 bit dưới dạng chuỗi thập phân để tránh mất độ chính xác. Bỏ qua để không lọc theo ID. Các bộ lọc khác và phân trang vẫn áp dụng.",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "Số trang hiện tại (bắt đầu từ 1)",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "Số lượng mục trên mỗi trang",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "Liệu proxy có được sử dụng cho điện thoại đám mây hay không.\n\n- `true`: Loại trừ các địa chỉ IP cục bộ/riêng tư (ví dụ: 127.0.0.1, 360, pia, các dải IP riêng tư)\n- `false`: Trả về tất cả các proxy\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "Loại danh mục proxy:\n- `1` = Nền tảng đám mây\n- `2` = IP tự sở hữu\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Lọc theo địa chỉ IP của máy chủ proxy (khớp một phần)",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Lọc theo tên máy chủ proxy (khớp một phần)",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Danh sách ID Loại proxy. Các giá trị được hỗ trợ:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "Trạng thái phân bổ proxy:\n- `0` = Bình thường\n- `1` = Chưa được phân bổ\n- `2` = Đang nâng cấp\n- `3` = Đã hết hạn\n- `4` = Sắp hết hạn\n> Lưu ý: Proxy tự sở hữu luôn sử dụng trạng thái `1`.",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "Trạng thái kiểm tra sức khỏe của máy chủ proxy:\n- `0` = Đang chờ xử lý\n- `1` = Thành công\n- `2` = Thất bại\n- `3` = Lỗi không xác định\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Các loại giao thức proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data.dataList` chứa các bản ghi của trang được yêu cầu và là mảng rỗng khi không có kết quả khớp; `data.total`, `data.current` và `data.pages` mô tả phân trang.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "Thời gian hết hạn",
                                "type": "string"
                              },
                              "id": {
                                "description": "Khóa chính",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "Loại proxy 1: Proxy nền tảng; 2: Proxy tự sở hữu",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "Trạng thái phát hiện: 0 - đang chờ phát hiện, 1 - giám sát thành công, 2 - phát hiện thất bại, 3 - lỗi không xác định.",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Bang hoặc tỉnh của proxy. Ưu tiên vị trí IP đầu ra được phát hiện, sau đó dùng vị trí cấu hình; có thể là null hoặc chuỗi rỗng.",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Thành phố của proxy. Ưu tiên vị trí IP đầu ra được phát hiện, sau đó dùng vị trí cấu hình; có thể là null hoặc chuỗi rỗng.",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "Cổng kết nối proxy, không suy ra từ tên proxy. Có thể là null nếu không có.",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "Địa chỉ IP proxy",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "xuất khẩu IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "mã quốc gia",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "Tên Proxy",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "Loại proxy: giá trị mặc định 0-HTTP 1-HTTPS 2-SOCKS5 3-SSH 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan，11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "Loại Proxy: 0-http 1-https 2-socks5 3-ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "Tên người dùng ủy quyền",
                                "type": "string"
                              },
                              "password": {
                                "description": "Mật khẩu proxy",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "URL làm mới proxy",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/add": {
      "post": {
        "summary": "Thêm máy chủ proxy",
        "deprecated": false,
        "description": "Tạo một cấu hình proxy trong nhóm.\n- **Điều kiện tiên quyết**: `proxyPort` là bắt buộc và phải nằm trong 1–65535, còn `proxyProvider` phải là một dịch vụ thiết bị được nhận diện.\n- **Tác động**: chèn một bản ghi proxy và trả về ID của nó, sẵn sàng để gán cho các profile. Không có gì được gửi tới Loại proxy.\n- **Hoàn tất**: đồng bộ.\n- **Thử lại**: **không có bước kiểm tra trùng tên hay trùng cấu hình.** Gửi cùng một request body hai lần sẽ tạo ra hai proxy với hai ID. Sau khi hết thời gian chờ, hãy tìm trong `/proxyInfo/page` trước khi gửi lại.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `14023`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "Thành phố",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "Mã quốc gia (ISO 3166-1 alpha-2). Chỉ bắt buộc nếu proxyProvider=17.\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Loại mã hóa, các giá trị hợp lệ là các số nguyên từ 1 đến 14.",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Hành động khi thay đổi địa chỉ IP: 0 = Chặn, 1 = Cảnh báo",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Bật tính năng giám sát thay đổi địa chỉ IP",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "Mật khẩu để xác thực proxy",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Địa chỉ IP proxy",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Tên proxy (hỗ trợ các ký tự đại diện như {{random}})",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Số cổng proxy",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Loại Loại proxy:\n0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH, 4=Oxylabs, 5=Proxys.io, 6=GeoSurf, 7=Luminati, 8=Lumauto, 9=Oxylabsauto, 10=Trojan, 11=Shadowsocks, 12=vmess, 13=ABCPROXY, 14=LunaProxy, 15=IPHTML, 16=PiaProxy, 17=922S5.\n\nQuy tắc đặc biệt:\n- Nếu proxyProvider là 7 hoặc 8, proxyType là bắt buộc.\n\n- Nếu proxyProvider là 17, quốc gia là bắt buộc; tiểu bang và thành phố là tùy chọn.\n",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Loại giao thức proxy: 0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH.\n\nChỉ cần thiết khi proxyProvider là 7 hoặc 8.\n",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL để làm mới địa chỉ IP proxy động (nếu được hỗ trợ)",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "Tiểu bang/Tỉnh",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "Tên người dùng để xác thực proxy",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một giá trị số nguyên duy nhất.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "ID ủy quyền",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/update": {
      "post": {
        "summary": "Sửa đổi thông tin proxy",
        "deprecated": false,
        "description": "Cập nhật một cấu hình proxy.\n- **Điều kiện tiên quyết**: proxy phải tồn tại trong nhóm. **Không thể cập nhật proxy động** qua endpoint này. Dịch vụ thiết bị phải là một giá trị được nhận diện.\n- **Tác động**: đây là ghi đè toàn bộ, không phải cập nhật từng phần — các trường bạn bỏ trống sẽ trở về giá trị mặc định chứ không giữ giá trị hiện tại. Hãy đọc proxy ra trước rồi gửi lại đầy đủ.\n- **Phạm vi áp dụng**: các profile vẫn giữ liên kết vì chỉ bản ghi proxy thay đổi, nhưng một trình duyệt hoặc cloud phone đang chạy vẫn tiếp tục dùng thông tin kết nối mà nó đã khởi động cùng. Hãy khởi động lại nó để áp dụng thông tin mới.\n- **Hoàn tất**: đồng bộ. Không có khóa lạc quan, nên các lần cập nhật đồng thời sẽ lấy lần ghi cuối cùng.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `14003`, `14023`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID ủy quyền duy nhất"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Địa chỉ IP của máy chủ proxy"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "Cổng máy chủ proxy"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Tên tùy chỉnh cho máy chủ proxy"
                  },
                  "country": {
                    "type": "string",
                    "description": "Quốc gia (ví dụ: \"Mỹ\", \"Trung Quốc\")"
                  },
                  "city": {
                    "type": "string",
                    "description": "Tên thành phố"
                  },
                  "username": {
                    "type": "string",
                    "description": "Tên người dùng xác thực (nếu cần)"
                  },
                  "password": {
                    "type": "string",
                    "description": "Mật khẩu xác thực (nếu cần)"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "Loại giao thức proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "Mã định danh Loại proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "Loại mã hóa (tùy thuộc vào dịch vụ thiết bị, thường là 0 cho dạng văn bản thuần)"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Bật tính năng giám sát thay đổi địa chỉ IP"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "Hành động cần thực hiện khi địa chỉ IP thay đổi:\n- `1` = Thông báo / Làm mới (giá trị thông thường)\n> Kiểm tra tài liệu hệ thống để biết đầy đủ các tùy chọn.\n"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL để kích hoạt làm mới địa chỉ IP (nếu dịch vụ thiết bị hỗ trợ)"
                  },
                  "state": {
                    "type": "string",
                    "description": "Trường dành riêng hoặc trạng thái tùy chỉnh (tùy chọn)"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. Thao tác này không trả về payload; kết quả được thể hiện qua `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/delete": {
      "post": {
        "summary": "Xóa máy chủ proxy",
        "deprecated": false,
        "description": "Xóa một hoặc nhiều cấu hình proxy.\n- **Điều kiện tiên quyết**: ít nhất một ID phải tra cứu được trong nhóm; những ID không tra cứu được sẽ bị bỏ qua âm thầm. **Không thể xóa một proxy nền tảng cloud chưa hết hạn** — trường hợp này được báo bằng một mã lỗi riêng.\n- **Tác động**: proxy tự sở hữu bị loại bỏ và được hủy liên kết khỏi mọi jump server. Một proxy nền tảng cloud đã hết hạn thì thay vào đó được đánh dấu chờ giải phóng, đăng ký của nó bị hủy, và IP được giải phóng **không đồng bộ** — quá trình giải phóng có thể vẫn đang diễn ra khi phản hồi trả về.\n- **Ảnh hưởng lan truyền**: các profile và cloud phone đang gán proxy này **không bị chặn cũng không được hủy gán**. Chúng vẫn tiếp tục trỏ tới proxy đã bị xóa, và các phiên đang chạy không bị ngắt. Hãy gán lại chúng bằng `/env/setProxy/batch` trước khi xóa.\n- **Thử lại**: các ID được xử lý lần lượt và lệnh gọi dừng lại ở lần từ chối đầu tiên, nên lô có thể chỉ được áp dụng một phần. Hãy đọc lại `/proxyInfo/page` trước khi thử lại.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `14017`, `14024`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. Thao tác này không trả về payload; kết quả được thể hiện qua `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/page": {
      "post": {
        "operationId": "apiEnvgroupPagePost",
        "summary": "Lấy danh sách các nhóm",
        "deprecated": false,
        "description": "Liệt kê theo trang các nhóm profile.\n- **Tác động**: không có. Chỉ đọc. An toàn khi thử lại với thời gian chờ tăng dần có giới hạn.\n- **Lưu ý**: khi nhóm làm việc phân quyền theo từng nhóm, một thành viên chưa được cấp nhóm nào sẽ nhận một trang rỗng thay vì lỗi.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "Tên nhóm (khớp một phần)"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "Trang hiện tại"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "Số mục mỗi trang"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data.dataList` chứa các bản ghi của trang được yêu cầu và là mảng rỗng khi không có kết quả khớp; `data.total`, `data.current` và `data.pages` mô tả phân trang.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "Mã nhóm",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "Tên nhóm",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/edit": {
      "post": {
        "operationId": "apiEnvgroupEditPost",
        "summary": "Chỉnh sửa thông tin nhóm",
        "deprecated": false,
        "description": "Đổi tên một nhóm profile.\n- **Điều kiện tiên quyết**: nhóm phải tồn tại trong nhóm làm việc, bên gọi phải có quyền với nó, và tên mới không được trùng với nhóm khác. Bước kiểm tra trùng tên chỉ chạy khi tên thực sự thay đổi.\n- **Tác động**: đổi tên nhóm. Các profile vẫn ở trong đó — chúng tham chiếu nhóm theo ID, nên không cần cập nhật gì khác.\n- **Hoàn tất**: đồng bộ và idempotent.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "Tên mới cho nhóm bảo vệ môi trường"
                  },
                  "id": {
                    "type": "string",
                    "description": "Mã định danh duy nhất của nhóm cần cập nhật"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một giá trị boolean duy nhất.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "kết quả"
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/create": {
      "post": {
        "operationId": "apiEnvgroupCreatePost",
        "summary": "Thêm nhóm",
        "deprecated": false,
        "description": "Tạo một nhóm profile.\n- **Điều kiện tiên quyết**: tên không được rỗng, tối đa 100 ký tự, và chưa được một nhóm khác trong nhóm làm việc sử dụng. **Mỗi nhóm làm việc bị giới hạn 1000 nhóm.**\n- **Tác động**: tạo nhóm. Khi nhóm làm việc phân quyền theo từng nhóm và bên gọi không phải chủ sở hữu, bên gọi cũng được cấp quyền truy cập nhóm mới.\n- **Hoàn tất**: đồng bộ; `data` mang ID của nhóm mới.\n- **Thử lại**: tên trùng sẽ bị từ chối chứ không dùng lại nhóm đã có, nên nếu bạn thử lại sau một lệnh gọi thực ra đã thành công nhưng bạn không nhận được phản hồi, lần thử lại sẽ báo lỗi trùng tên — chính đó là dấu hiệu lần gọi đầu đã thành công. Hãy xác nhận bằng `/envgroup/page`.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName"
                ],
                "properties": {
                  "groupName": {
                    "description": "Tên nhóm",
                    "type": "string"
                  }
                }
              },
              "example": {
                "groupName": "Group-333"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một đối tượng với các trường `id` và `groupName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "Dữ liệu được trả về bởi thao tác",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID của nhóm",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "Tên nhóm",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/delete": {
      "post": {
        "operationId": "apiEnvgroupDeletePost",
        "summary": "Xóa nhóm",
        "deprecated": false,
        "description": "Xóa một hoặc nhiều nhóm profile.\n- **Điều kiện tiên quyết**: ít nhất một ID phải tra cứu được trong nhóm làm việc và bên gọi phải có quyền với nó; các ID không tra cứu được sẽ bị bỏ qua âm thầm.\n- **Tác động**: xóa các nhóm và quyền truy cập đã cấp cho thành viên theo chúng. Các profile trình duyệt và cloud phone từng ở trong đó sẽ trở thành chưa thuộc nhóm nào, nên không để lại tham chiếu nhóm mồ côi. Bật cờ xóa luôn môi trường sẽ chuyển thêm các profile mà bạn có quyền **vào thùng rác** — chúng không bị hủy, và cờ này không bao giờ tác động tới cloud phone.\n- **Hoàn tất**: đồng bộ nhưng **không nguyên tử**. Nhóm bị xóa trước, và các bước sau vẫn có thể thất bại, chẳng hạn khi một profile đang chạy hoặc đang chuyển giao, để lại kết quả là nhóm đã mất mà profile chưa được chuyển đi.\n- **Thử lại**: hãy kiểm chứng bằng `/envgroup/page` và danh sách profile trước khi thử lại.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `19064`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "ID duy nhất của nhóm cần cập nhật"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "Xóa các môi trường trong nhóm? false: không xóa; true: xóa"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một giá trị boolean duy nhất.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/all": {
      "get": {
        "operationId": "apiEnvtagAllGet",
        "summary": "Lấy danh sách thẻ",
        "deprecated": false,
        "description": "Trả về mọi thẻ profile trong nhóm.\n- **Tác động**: không có. Chỉ đọc. An toàn khi thử lại với thời gian chờ tăng dần có giới hạn.\n- **Lưu ý**: endpoint này **không phân trang và thẻ không có giới hạn phía server**, nên phản hồi sẽ lớn dần theo số thẻ mà nhóm bạn đã tạo. Hãy thiết kế client tương ứng.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Thành công. `data` là mảng các đối tượng với các trường `id` và `tagName`, và là mảng rỗng khi không có gì để trả về.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "ID của thẻ",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "Tên thẻ",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/create": {
      "post": {
        "operationId": "apiEnvtagCreatePost",
        "summary": "Tạo thẻ",
        "deprecated": false,
        "description": "Tạo một thẻ profile.\n- **Điều kiện tiên quyết**: tên không được rỗng, tối đa 100 ký tự, và chưa được một thẻ khác trong nhóm sử dụng.\n- **Tác động**: tạo thẻ và trả về ID của nó. Khác với nhóm, thẻ không có giới hạn số lượng.\n- **Thử lại**: tên trùng sẽ bị từ chối chứ không dùng lại thẻ đã có. Hãy xác nhận bằng `/envtag/all`.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tagName"
                ],
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "tên thẻ"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một đối tượng với các trường `id` và `tagName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID của thẻ",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "Tên thẻ",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/edit": {
      "post": {
        "operationId": "apiEnvtagEditPost",
        "summary": "Chỉnh sửa thông tin của thẻ",
        "deprecated": false,
        "description": "Đổi tên một thẻ profile.\n- **Điều kiện tiên quyết**: thẻ phải tồn tại trong nhóm, và tên mới không được trùng với thẻ khác.\n- **Tác động**: đổi tên thẻ. Các liên kết thẻ hiện có không bị ảnh hưởng và các profile hiển thị tên mới ngay lập tức.\n- **Hoàn tất**: đồng bộ và idempotent.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "tagName"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID thẻ"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "tên thẻ"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một giá trị boolean duy nhất.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/delete": {
      "post": {
        "operationId": "apiEnvtagDeletePost",
        "summary": "Xóa thẻ",
        "deprecated": false,
        "description": "Xóa một hoặc nhiều thẻ profile.\n- **Điều kiện tiên quyết**: ít nhất một ID phải tra cứu được trong nhóm; những ID không tra cứu được sẽ bị bỏ qua âm thầm.\n- **Tác động**: xóa các thẻ. Thẻ biến mất khỏi mọi profile từng mang nó, và không profile nào bị xóa. Endpoint này chỉ quản lý thẻ profile — thẻ tệp Cloud Storage được quản lý riêng.\n- **Hoàn tất**: đồng bộ. Gọi lại sẽ báo các thẻ không hợp lệ, điều đó nghĩa là lần gọi đầu đã thành công.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `19105`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "ID duy nhất của thẻ cần cập nhật"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một giá trị boolean duy nhất.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã trả về 0: Bình thường. Các mã khác là ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID yêu cầu vận hành",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/webhook/config": {
      "post": {
        "operationId": "apiWebhookConfigPost",
        "summary": "Cấu hình webhook của nhóm",
        "deprecated": false,
        "description": "Tạo mới hoặc thay thế cấu hình webhook của nhóm.\n\n- **Điều kiện tiên quyết**: `callbackUrl` phải là URL HTTPS dài từ 1 đến 1024 ký tự, có tên host, không chứa thông tin người dùng, không có fragment và cổng hợp lệ. Mọi địa chỉ mà nó phân giải ra đều phải định tuyến được trên internet; các dải localhost, riêng tư, link-local, CGNAT, metadata đám mây, dải dành riêng cho giao thức, dải dùng cho tài liệu và 6to4 sẽ bị từ chối. Cùng phép kiểm tra đó được thực hiện lại khi một lần gửi mở kết nối, nên một tên miền sau này phân giải vào dải riêng tư chỉ làm lần gửi đó thất bại chứ không chạm tới mạng của bạn.\n- **Tác động**: upsert cấu hình duy nhất thuộc nhóm trong ngữ cảnh phía máy chủ. `teamId` không bao giờ được đọc từ request, nên người gọi không thể cấu hình cho nhóm khác. Endpoint của Local API và Open API đọc và ghi cùng một bản ghi, và phản hồi phản ánh nội dung đã lưu.\n- **Tắt**: `enabled: false` giữ lại URL và dừng việc tạo sự kiện mới. Các sự kiện đã nằm trong hàng đợi sẽ bị hủy lần lượt nếu cấu hình vẫn đang tắt khi chúng được cấp phép lần kế tiếp, nên bật lại sớm sẽ cho chúng tiếp tục.\n- **Thử lại**: an toàn. Việc lưu là upsert theo nhóm, nên gửi lại cùng một request sẽ hội tụ về cùng một trạng thái.\n- **Phiên bản client**: cần client MoreLogin v2.66.0 trở lên, vì chính client máy tính mới expose route này ở local. Endpoint của Open API không phụ thuộc client.\n\nXem [Webhooks](../Getting%20Started/webhooks.md) để biết hợp đồng callback, tên sự kiện và lịch thử lại.\n\nCác mã lỗi nghiệp vụ đã ghi nhận: `41001`. Xem [Error Codes](../Getting%20Started/error-codes.md) để biết ý nghĩa từng mã. Mọi thao tác cũng có thể trả về các mã dùng chung.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "URL HTTPS nhận sự kiện. Từ 1 đến 1024 ký tự.",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "Việc gửi sự kiện có được bật cho nhóm hay không.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thành công. `data` là một đối tượng có các trường `callbackUrl` và `enabled`, phản ánh cấu hình đã lưu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Mã kết quả. `0` là thành công; các mã khác biểu thị ngoại lệ.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Thông báo lỗi",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "URL callback HTTPS đã lưu.",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "Việc gửi sự kiện có được bật cho nhóm hay không.",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID yêu cầu của thao tác",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    }
  },
  "webhooks": {},
  "components": {
    "securitySchemes": {}
  },
  "servers": [
    {
      "url": "http://127.0.0.1:40000",
      "description": "Điểm cuối Local của MoreLogin"
    }
  ],
  "security": []
}